package com.hqd.ch03.v50.boot.context.config;

import com.hqd.ch03.v50.boot.origin.Origin;
import com.hqd.ch03.v50.boot.origin.OriginProvider;
import com.hqd.ch03.v50.utils.StringUtils;

public final class ConfigDataLocation implements OriginProvider {

    public static final String OPTIONAL_PREFIX = "optional:";

    /**
     * 是否可选
     */
    private final boolean optional;
    /**
     * 路径
     */
    private final String value;

    /**
     * 配置文件源
     */
    private final Origin origin;

    private ConfigDataLocation(boolean optional, String value, Origin origin) {
        this.value = value;
        this.optional = optional;
        this.origin = origin;
    }

    public static ConfigDataLocation of(String location) {
        boolean optional = location != null && location.startsWith(OPTIONAL_PREFIX);
        String value = (!optional) ? location : location.substring(OPTIONAL_PREFIX.length());
        if (!StringUtils.hasText(value)) {
            return null;
        }
        return new ConfigDataLocation(optional, value, null);
    }

    public boolean isOptional() {
        return this.optional;
    }

    public String getValue() {
        return this.value;
    }

    public boolean hasPrefix(String prefix) {
        return this.value.startsWith(prefix);
    }

    public String getNonPrefixedValue(String prefix) {
        if (hasPrefix(prefix)) {
            return this.value.substring(prefix.length());
        }
        return this.value;
    }

    @Override
    public Origin getOrigin() {
        return this.origin;
    }

    /**
     * 默认分号作为分隔符
     *
     * @return
     */
    public ConfigDataLocation[] split() {
        return split(";");
    }

    public ConfigDataLocation[] split(String delimiter) {
        /**
         * 分割字符串
         */
        String[] values = StringUtils.delimitedListToStringArray(toString(), delimiter);
        ConfigDataLocation[] result = new ConfigDataLocation[values.length];
        for (int i = 0; i < values.length; i++) {
            result[i] = of(values[i]).withOrigin(getOrigin());
        }
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null || getClass() != obj.getClass()) {
            return false;
        }
        ConfigDataLocation other = (ConfigDataLocation) obj;
        return this.value.equals(other.value);
    }

    @Override
    public int hashCode() {
        return this.value.hashCode();
    }

    @Override
    public String toString() {
        return (!this.optional) ? this.value : OPTIONAL_PREFIX + this.value;
    }

    ConfigDataLocation withOrigin(Origin origin) {
        return new ConfigDataLocation(this.optional, this.value, origin);
    }

}
